/*
 * User: user
 * Date: 12/02/2008
 * Time: 11:20:51
 */
package org.conann.container;

import static com.google.common.base.Preconditions.checkNotNull;
import com.google.common.collect.Maps;
import com.google.common.collect.Multimap;
import com.google.common.collect.Multimaps;
import org.conann.metadata.BasicRecordsRegistry;
import org.conann.metadata.BeanMD;
import org.conann.metadata.RecordsRegistry;
import org.conann.metadata.records.TypeRecord;

import javax.webbeans.Bean;
import java.lang.reflect.AnnotatedElement;
import java.util.Set;
import java.util.concurrent.ConcurrentMap;

public class MetadataRegistry {

    private final Multimap<Class<?>, Class<?>> conformingTypes = Multimaps.newHashMultimap();
    private final RecordsRegistry recordsRegistry = new BasicRecordsRegistry();
    private final ConcurrentMap<AnnotatedElement, BeanMD> componentMDs = Maps.newConcurrentHashMap();
    @Deprecated
    private BeansRegistry beansRegistry;

    @Deprecated
    public Set<Class<?>> getImplementingTypes(Class<?> apiType) {
        checkNotNull(apiType);
        return (Set<Class<?>>) conformingTypes.get(apiType);
    }

    public Set<Bean<?>> getImplementingComponents(Class<?> apiType) {
        return beansRegistry.getConformingBeans(apiType);
    }

    public void addSimpleComponent(Class<?> type) {
        checkNotNull(type);
        beansRegistry.addSimpleComponent(type);
    }

    public <T> TypeRecord<T> getRecord(Class<T> type) {
        return recordsRegistry.getRecord(type);
    }

    public <T> Bean<T> getComponent(Class<T> type) {
        checkNotNull(type);
        return beansRegistry.getComponent(type);
    }

    public BeanMD getComponentMD(AnnotatedElement element) {
        BeanMD beanMD = componentMDs.get(element);
        if (beanMD == null) {
            componentMDs.putIfAbsent(element, new BeanMD(element));
            beanMD = componentMDs.get(element);
        }
        return beanMD;
    }
}